Structuring Your Site

Publish Overview

By following the instructions on John Sundell's GitHub page, you can set up a Website on your mac complete with a server to view the results in Safari. I kid you not when I say you can have a functional site set up on your mac in less than an hour. How is that even possible?

John has spent lot of time and effort creating the tools needed and organizing how everything fits together. Before hacking away at things, let's take a look at how things are set up out of the box, and some of the underlying reasons why things are organized the way they are. Once you have a basic understanding of how things work, you'll have an easier time making changes to customize how the site works for you.

This page outlines some of the conventions to follow while getting your feet wet. As I say often on this site: there's more than one way to do things. But until you can introduce changes to your site and view the results right away, you might feel a bit lost. I recommend you follow the conventions until you are more familiar with how everything fits together.

Remember that the type of object we create is a Website. By creating a custom Website object you are going to be met with a lot of decision making along the way. If you are going to use any of the extra tools (like Plot or Splash) that are developed for working with Publish, then it makes sense not to stray too far from the intended structure. At least, until you understand how the pieces fit together/What makes things tick.

The Folder Layout

The Content Folder

Content is where you put your website's written content -- blog posts, and other pages.

Publish

Publish lets you generate your website's content in two ways: by using markdown files or programmatically. When you add markdown files to Content, Publish parses the content automatically. It (automatically) uses Ink markdown parser library, also created by John Sundell. All of this is fairly transparent to you. I mostly add markdown files that are ready for display, and tend to not do this programmatically. If there's any demand I can come up with a demo file or two using Plot. Plot is John Sundell's plugin that enables you to "program" your output files with methods such as li() for list items and a() to define links. The advantage to doing things this way is you have the compiler checking your work as you go along.

Output

Output is the main folder of the website. It contains all the files necessary to display the content of the website. It's generated every time you build the project in Xcode. Once you start adding more content and custom pages to your website, you'll see more files and folders appear. You should assume everything in this file is read-only. After any changes to your source files or resources, a rebuild or running your project will trigger an update of the content of this folder.

Even though you don't add to or edit anything in this folder, it contains all the content and information to generate your website. Consider it as read-only. You'll see feed and sitemap files there along with styles.css. This CSS file is the pre-defined styling for your website. You can create your own theme, which in turn can use a custom styles.css file to display your content with a uniform feel and look.

Resources

Resources is where you add any media files for your content, like images, videos, audio, and fonts.

Sources

Sources has all the Swift files to build your website. On initial install there's one main.swift file which contains configuration information for your website. You can add sections, specific item metadata, website properties, and configure publishing steps. Typically you issue the command to "publish" your site at the bottom of this file.

The Three Major DataTypes Used By the System

Section, Item, and Page

Sections

There are three major data types used to help you structure your content.

Each of these is called at the appropriate time whenever you build/publish/run your site.

Each Section, Item, and Page can define its own set of Content — which can range from text (like titles and descriptions), to HTML, audio, video and various kinds of metadata.

The Theme struct (defined as part of the Publish API) provides you with processing hooks to let you customize how each is processed.

public struct Theme<Site: Website> {
    internal let makeIndexHTML: (Index, PublishingContext<Site>) throws -> HTML
    internal let makeSectionHTML: (Section<Site>, PublishingContext<Site>) throws -> HTML
    internal let makeItemHTML: (Item<Site>, PublishingContext<Site>) throws -> HTML
    internal let makePageHTML: (Page, PublishingContext<Site>) throws -> HTML
    internal let makeTagListHTML: (TagListPage, PublishingContext<Site>) throws -> HTML?
    internal let makeTagDetailsHTML: (TagDetailsPage, PublishingContext<Site>) throws -> HTML?
    internal let resourcePaths: Set<Path>
    internal let creationPath: Path
    ...
    }

Each Section, Item, and Page can define its own set of Content — which can range from text (like titles and descriptions), to HTML, audio, video and various kinds of metadata.

Sections are created based on the members of each website’s SectionID enum. Each section both has its own HTML page, and can also act as a container for a list of Items.

Items represent the individual entries (blog posts, for example) and can exist as nested HTML pages within a section.

Pages provide yet another way to build custom pages. You can create free-form pages that can be placed into any kind of folder hierarchy.

For the most part, this is the typical structure used by most developers but I've noticed not everyone follows this layout. I recommend you start by adopting this three folder concept - at least until you are comfortable you understand where everything is and why it's there.

Metadata

Publish makes use of the ItemMetadata type if you choose to give it properties. You can add metadata to the top of your files which, if defined, must match the fields in your ItemMetadata object. A missing field, or a field in the wrong format will stop the compile.

Tags

Tags can make for a convenient way to filter, sort or group your content. It is easy to add functionality to your site by processing content by tag (you can add your own PublishingStep to the build process). An item can have more than one tag.

Publishing Steps

You can think of a publishing step as a component of a composable sequence used to create your site. Each publishing step is passed an instance of PublishingContext, which it can use to mutate the current context in which the website is being published — including its files, folders, and content. This gives you a lot of freedom to enhance the site to better suit your specific needs.

The main file

As I mentioned, main is pretty much the only source code file you will find after an initial install. That should signal to you that important stuff goes here. Most tutorials I've seen recommend copying the Foundation theme which ships with Publish. This quickly becomes the most important file, as it can be used as the control center for customizing the site to your needs.


Creating a Custom Theme - Russell Gordon

Creating Content With Markdown

Wrestling With Publish